import uuid
from typing import List

from sqlalchemy import delete, insert, select

from forward.api.admin.config import AdminConfig
from forward.api.admin.schemas.system import (
    SystemAuthMenuOutSchema,
    SystemAuthRoleOutSchema,
)
from forward.dependencies.database import db
from forward.model.tables import SystemAuthMenuModel, SystemAuthPermModel, SystemAuthRoleModel
from forward.utils.redis import RedisUtil


class SystemAuthPermService:
    """系统权限服务实现类"""

    @classmethod
    async def select_menu_ids_by_role_id(cls, role_ids: List[int]) -> List[int]:
        """根据角色ID获取菜单ID"""
        role_record = await db.fetch_one(
            select(SystemAuthRoleModel).where(
                SystemAuthRoleModel.id.in_(role_ids),
                SystemAuthRoleModel.is_disable == 0,
            )
        )
        if not role_record:
            return []
        menu_records = await db.fetch_all(
            select(SystemAuthMenuModel)
            .select_from(SystemAuthMenuModel)
            .join(
                SystemAuthPermModel,
                SystemAuthPermModel.menu_id == SystemAuthMenuModel.id,
            )
            .where(SystemAuthPermModel.role_id.in_(role_ids))
        )

        perms = [
            SystemAuthMenuOutSchema.model_validate(menu_record, from_attributes=True)
            for menu_record in menu_records
        ]
        return [i.id for i in perms]

    @classmethod
    async def cache_role_menus_by_role_id(cls, role_id: int):
        """缓存角色菜单"""
        menu_records = await db.fetch_all(
            select(SystemAuthMenuModel)
            .select_from(SystemAuthMenuModel)
            .join(
                SystemAuthPermModel,
                SystemAuthPermModel.menu_id == SystemAuthMenuModel.id,
            )
            .where(SystemAuthPermModel.role_id == role_id)
            .where(
                SystemAuthMenuModel.is_disable == 0,
                SystemAuthMenuModel.menu_type.in_(["C", "A"]),
            )
        )

        menus = [
            SystemAuthMenuOutSchema.model_validate(
                menu_record, from_attributes=True
            ).perms
            for menu_record in menu_records
        ]

        await RedisUtil.hset(
            AdminConfig.backstage_roles_key, str(role_id), ",".join(menus)
        )

    @db.transaction()
    async def batch_save_by_menu_ids(self, role_id: int, menu_ids: str):
        """批量写入角色菜单"""
        if menu_ids:
            perms = []
            for menu_id in menu_ids.split(","):
                perms.append(
                    {
                        "id": uuid.uuid4().hex,
                        "role_id": role_id,
                        "menu_id": int(menu_id),
                    }
                )
            perm_ins = insert(SystemAuthPermModel).values(perms)
            await db.execute(perm_ins)

    async def batch_delete_by_role_id(self, role_id: int):
        """批量删除角色菜单(根据角色ID)"""
        await db.execute(
            delete(SystemAuthPermModel).where(SystemAuthPermModel.role_id == role_id)
        )

    async def batch_delete_by_menu_id(self, menu_id: int):
        """批量删除角色菜单(根据菜单ID)"""
        await db.execute(
            delete(SystemAuthPermModel).where(SystemAuthPermModel.menu_id == menu_id)
        )

    @classmethod
    async def instance(cls):
        """实例化"""
        return cls()
